package cn.com.w.common.Utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.args.ExpiryOption;

/**
 * @author w
 * @Description:
 * @DateTime: 2025 05 09 17:02
 **/
public class JedisUtils {

    private static JedisPool jedisPool = null;

    /**
     * redis服务器地址
     */
    private static String addr = "127.0.0.1";

    /**
     * redis服务器端口
     */
    private static int port = 6379;

//    /**
//     * redis服务器密码
//     */
//    private static String auth = "";


    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            //连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
            config.setBlockWhenExhausted(true);
            //设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
            config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
            //是否启用pool的jmx管理功能, 默认true
            config.setJmxEnabled(true);
            //MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "pool" + i); 默认为"pool", JMX不熟,具体不知道是干啥的...默认就好.
            config.setJmxNamePrefix("pool");
            //是否启用后进先出, 默认true
            config.setLifo(true);
            //最大空闲连接数, 默认8个
            config.setMaxIdle(8);
            //最大连接数, 默认8个
            config.setMaxTotal(8);
//            //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
//            config.setMaxWaitMillis(-1);
//            //逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
//            config.setMinEvictableIdleTimeMillis(1800000);
            //最小空闲连接数, 默认0
            config.setMinIdle(0);
            //每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
            config.setNumTestsPerEvictionRun(3);
//            //对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断  (默认逐出策略)
//            config.setSoftMinEvictableIdleTimeMillis(1800000);
            //在获取连接的时候检查有效性, 默认false
            config.setTestOnBorrow(false);
            //在空闲时检查有效性, 默认false
            config.setTestWhileIdle(false);
//            //逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
//            config.setTimeBetweenEvictionRunsMillis(-1);
            jedisPool = new JedisPool(config, addr, port, 3000);
            LogUtils.getLogger().info("redis启动成功");
        } catch (Exception e) {
            LogUtils.getLogger().error("redis启动失败{}", e.getMessage());
        }
    }

    /**
     * 获取 Jedis 资源
     *
     * @return
     */
    public static Jedis getJedis() {
        if (jedisPool != null) {
            return jedisPool.getResource();
        }
        return null;
    }

    /**
     * 释放Jedis资源
     */
    public static void close(final Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * 添加一个键值对并设置过期时间
     * @param key 键
     * @param value 值
     * @param seconds 过期时间（秒）
     */
    public static void setWithExpire(String key, String value, long seconds) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            if (jedis != null) {
                // 添加键值对
                jedis.set(key, value);
                // 设置过期时间 单位 秒
                jedis.expire(key, seconds);
            }
        } catch (Exception e) {
            LogUtils.getLogger(JedisUtils.class).error("添加键值对并设置过期时间失败: {}", e.getMessage());
        } finally {
            close(jedis);
        }
    }

}
